home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d13 / devdvr.arc / DRIVER.ASM < prev    next >
Assembly Source File  |  1986-09-01  |  18KB  |  629 lines

  1. 4
  2. Capture Buffer Transfer
  3. No error detection/correction
  4.  
  5. Opening capture buffer...
  6.         name    driver
  7.         page    55,132
  8.         title   'DRIVER --- installable driver template'
  9.  
  10. ;
  11. ; This is a "template" for a MS-DOS installable device driver.
  12. ; The actual driver subroutines are stubs only and have
  13. ; no effect but to return a non-error "done" status.
  14. ; Ray Duncan
  15. ; Laboratory Microsystems Inc.
  16. ; April 1985
  17.  
  18. code    segment public 'CODE'
  19.  
  20. driver  proc    far
  21.  
  22.         assume  cs:code,ds:code,es:code
  23.  
  24.         org     0
  25.  
  26.  
  27. Max_Cmd equ     15              ; MS-DOS command code maximum
  28.                                 ; this is 15 for MS-DOS 3.x
  29.                                 ; and 12 for MS-DOS 2.x 
  30.  
  31.  
  32. cr      equ     0dh             ; ASCII carriage return
  33. lf      equ     0ah             ; ASCII line feed
  34. eom     equ     '$'             ; end of message signal
  35.  
  36.  
  37.         page
  38. ;
  39. ; Device Driver Header
  40. ;
  41. Header  dd      -1              ;link to next device,-1= end of list
  42.  
  43.         dw      8000h           ;attribute word
  44.                                 ;bit 15=1 for character devices
  45.  
  46.         dw      Strat           ;device "Strategy" entry point
  47.  
  48.         dw      Intr            ;device "Interrupt" entry point
  49.  
  50.         db      'DRIVER  '      ;char device name, 8 char, or
  51.                                 ;if block device, no. of units
  52.                                 ;in first byte followed by 
  53.                                 ;7 don't care bytes     
  54.  
  55.  
  56.  
  57. ; Interpretation of Attribute word:
  58. ; Bit           Significance
  59. ;
  60. ; 15            =1 for character drivers
  61. ; 14            =1 if driver can handle IOCTL
  62. ; 13            =1 if block device & non-IBM format
  63. ; 12            0
  64. ; 11            open/close/RM supported (DOS 3.x)
  65. ; 10            0
  66. ;  9            0
  67. ;  8            0
  68. ;  7            0
  69. ;  6            0
  70. ;  5            0
  71. ;  4            0
  72. ;  3            =1 if CLOCK device
  73. ;  2            =1 if NUL device
  74. ;  1            =1 if Standard Output
  75. ;  0            =1 if Standard Input
  76.  
  77.         page
  78. ;
  79. ; local variables for use by driver
  80. ;
  81. RH_Ptr  dd      ?               ; pointer to request header
  82.                                 ; passed to Strat by BDOS
  83.  
  84. Ident   db      cr,lf,lf
  85.         db      'LMI Example Device Driver 1.0'
  86.         db      cr,lf
  87.         db      'Copyright (c) 1985 '
  88.         db      'Laboratory Microsystems Inc.' 
  89.         db      cr,lf,lf,eom
  90. ;
  91. ; MS-DOS Command Codes dispatch table.
  92. ; The "Interrupt" routine uses this table and the 
  93. ; Command Code supplied in the Request Header to 
  94. ; transfer to the appropriate driver subroutine.
  95.  
  96. Dispatch:
  97.         dw      Init            ;  0 = init driver into system
  98.         dw      Media_Chk       ;  1 = media check on blk dev
  99.         dw      Build_Bpb       ;  2 = build BIOS param block
  100.         dw      Ioctl_Inp       ;  3 = I/O ctrl read from dev
  101.         dw      Input           ;  4 = normal destructive read
  102.         dw      Nd_Input        ;  5 = non-destructive read,no wait
  103.         dw      Inp_Stat        ;  6 = return current input status
  104.         dw      Inp_Flush       ;  7 = flush device input buffers
  105.         dw      Output          ;  8 = normal output to device
  106.         dw      Outp_Vfy        ;  9 = output with verify
  107.         dw      Outp_Stat       ; 10 = return current output status
  108.         dw      Outp_Flush      ; 11 = flush output buffers
  109.         dw      Ioctl_Outp      ; 12 = I/O control output
  110.         dw      Dev_Open        ; 13 = device open      (MS-DOS 3.x)
  111.         dw      Dev_Close       ; 14 = device close     (MS-DOS 3.x)
  112.         dw      Rem_Media       ; 15 = removeable media (MS-DOS 3.x)
  113.         page
  114. ; MS-DOS Request Header structure definition
  115. ;
  116. ; The first 13 bytes of all Request Headers are the same
  117. ; and are referred to as the "Static" part of the Header.
  118. ; The number and meaning of the following bytes varies.
  119. ; In this "Struc" definition we show the Request Header
  120. ; contents for Read and Write calls.
  121. ;
  122. Request struc                   ; request header template structure
  123.         
  124.                                 ; beginning of "Static" portion
  125. Rlength db      ?               ; length of request header
  126. Unit    db      ?               ; unit number for this request
  127. Command db      ?               ; request header's command code
  128. Status  dw      ?               ; driver's return status word
  129. Reserve db      8 dup (?)       ; reserved area
  130.                                 ; end of "Static" portion       
  131.  
  132. Media   db      ?               ; media descriptor byte
  133. Address dd      ?               ; memory address for transfer
  134. Count   dw      ?               ; byte/sector count value
  135. Sector  dw      ?               ; starting sector value
  136.  
  137. Request ends                    ; end of request header template
  138.  
  139. ;
  140. ; Status word is interpreted as follows:
  141. ;
  142. ;  Bit(s)   Significance
  143. ;   15       Error
  144. ;   10-14    Reserved
  145. ;   9        Busy
  146. ;   8        Done
  147. ;   0-7      Error code if bit 15=1
  148.  
  149. ; Predefined BDOS error codes are:
  150. ;   0       Write protect violation
  151. ;   1       Unknown unit
  152. ;   2       Drive not ready
  153. ;   3       Unknown command
  154. ;   4       CRC error
  155. ;   5       Bad drive request structure length
  156. ;   6       Seek error
  157. ;   7       Unknown media
  158. ;   8       Sector not found
  159. ;   9       Printer out of paper
  160. ;   10      Write fault
  161. ;   11      Read fault
  162. ;   12      General failure     
  163. ;   13-14   Reserved
  164. ;   15      Invalid disk change  (MS-DOS 3.x)
  165.  
  166.         page
  167.  
  168. ; Device Driver "Strategy Routine"
  169.  
  170. ; Each time a request is made for this device, the BDOS
  171. ; first calls "Strategy routine",  then immediately calls
  172. ; the "Interrupt routine".  
  173.  
  174. ; The Strategy routine is passed the address of the
  175. ; Request Header in ES:BX, which it saves in a local
  176. ; variable and then returns to the BDOS.
  177.  
  178. Strat   proc    far     
  179.                                 ; save address of Request Header
  180.         mov     word ptr cs:[RH_Ptr],bx
  181.         mov     word ptr cs:[RH_Ptr+2],es
  182.  
  183.         ret                     ; back to BDOS
  184.  
  185. Strat   endp
  186.  
  187.         page
  188.  
  189.  
  190. ; Device Driver "Interrupt Routine"
  191.  
  192. ; This entry point is called by the BDOS immediately after 
  193. ; the call to the "Strategy Routine", which saved the long
  194. ; address of the Request Header in the local variable "RH_Ptr".
  195.  
  196. ; The "Interrupt Routine" uses the Command Code passed in
  197. ; the Request Header to transfer to the appropriate device
  198. ; handling routine.  Each command code routine is responsible
  199. ; for any necessary return information into the Request Header,
  200. ; then transfers to Error or Exit to set the Return Status code.
  201.  
  202. Intr    proc  far
  203.  
  204.         push    ax              ; save general registers 
  205.         push    bx
  206.         push    cx
  207.         push    dx
  208.         push    ds
  209.         push    es
  210.         push    di
  211.         push    si
  212.         push    bp
  213.  
  214.         push    cs              ; make local data addressable
  215.         pop     ds
  216.  
  217.         les     di,[RH_Ptr]     ; ES:DI = Request Header
  218.  
  219.                                 ; get BX = Command Code
  220.         mov     bl,es:[di.Command]
  221.         xor     bh,bh
  222.         cmp     bx,Max_Cmd      ; make sure its legal
  223.         jg      Unk_Command     ; too big, exit with error code
  224.         shl     bx,1            ; form index to Dispatch table
  225.                                 ; and branch to driver routine
  226.         jmp     word ptr [bx+Dispatch]
  227.  
  228.         page
  229.  
  230.  
  231. ; General collection of exit points for the driver routines.
  232.  
  233.  
  234. Unk_Command:                    ; Come here if Command Code too big.
  235.         mov     al,3            ; Sets "Unknown Command" error 
  236.                                 ; code and "Done" bit.
  237.  
  238. Error:                          ; Transfer here with AL = error code.
  239.         mov     ah,81h          ; Sets "Error" and "Done" bits.
  240.         jmp     Exit
  241.  
  242. Done:   mov     ah,1            ; Come here if I/O complete and
  243.                                 ; no error, sets "Done" bit only.
  244.  
  245.  
  246. Exit:                           ; General purpose exit point.
  247.                                 ; Transfer here with AX = 
  248.                                 ; Return Status word to be
  249.                                 ; placed into Request Header.
  250.  
  251.         lds     bx,cs:[RH_Ptr]          ; set status
  252.         mov     ds:[bx.Status],ax
  253.  
  254.         pop     bp              ;restore general registers
  255.         pop     si
  256.         pop     di
  257.         pop     es
  258.         pop     ds
  259.         pop     dx
  260.         pop     cx
  261.         pop     bx
  262.         pop     ax
  263.         ret                     ; back to BDOS
  264.  
  265.         page
  266.  
  267.  
  268. ; Function 1  Media Check
  269.  
  270. ; Block devices only.  Should be a NOP for character devices.
  271. ;
  272. ; This routine is called first by BDOS for a block device transfer,
  273. ; passing current media descriptor byte at Request Header + 
  274. ;
  275. ; Media Check routine sets status word and in addition passes back 
  276. ; return byte at Request Header + 14  as follows:
  277.  
  278. ;    -1  Media has been changed
  279. ;     0  Don't know if media changed
  280. ;     1  Media has not been changed
  281. ;
  282. ; If driver can return 1 or -1, performance is improved because
  283. ; MS-DOS does not need to reread the FAT for each directory access.
  284.  
  285.  
  286. Media_Chk:
  287.  
  288.         jmp     Done
  289.  
  290.         page
  291.  
  292. ;
  293. ; Function 2  Build BIOS Parameter Block
  294. ; Block devices only.  Should be a NOP for character devices.
  295. ;
  296. ; This routine is called by MS-DOS when Media-Changed code is
  297. ; returned by Media Check routine, or if Not Sure code is returned
  298. ; and there are no dirty buffers.
  299. ; Build BPB call receives pointer to one-sector buffer in Address
  300. ; Field of Request Header (offset 14).  If "Non-IBM-Format" bit 
  301. ; in attribute word is zero, the buffer contains the first sector
  302. ; of the FAT including the media identification byte and should not 
  303. ; be altered by the driver.   If the "Non-IBM-Format" bit is set, 
  304. ; the buffer may be used as scratch space.
  305. ;
  306. ; The Build BPB routine sets status and returns a DWORD pointer to 
  307. ; the new Bios Parameter Block at Request Header + 18.
  308. ;
  309.  
  310. Build_Bpb:
  311.  
  312.         jmp     Done
  313.  
  314.         page
  315.  
  316. ;
  317. ; Function 3  I/O Control Read 
  318. ; Only called if IOCTL bit set in Device Header Attribute word.
  319. ;
  320. ; Called with:
  321. ;
  322. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  323. ; Request Header + 14  DWORD  Transfer address
  324. ; Request Header + 18  WORD   byte/sector count
  325. ; Request Header + 20  WORD   starting sector no. (block dev.)
  326. ;
  327. ; Returns the Return Status word set appropriately, and
  328. ; Request Header + 18  WORD   actual bytes or sectors transferred
  329. ; No error check is performed on IOCTL I/O calls.
  330.  
  331. Ioctl_Inp:
  332.  
  333.         jmp     Done
  334.  
  335.         page
  336.  
  337. ;
  338. ; Function 4  Read from Device
  339. ;
  340. ; Called with
  341. ;
  342. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  343. ; Request Header + 14  DWORD  Transfer address
  344. ; Request Header + 18  WORD   byte/sector count
  345. ; Request Header + 20  WORD   starting sector no. (block dev.)
  346. ;
  347. ; Returns the Return Status word set appropriately, and
  348. ; Request Header + 18  WORD   actual bytes or sectors transferred
  349.  
  350. Input: 
  351.  
  352.         jmp     Done
  353.  
  354.         page
  355.  
  356. ;
  357. ; Function 5  Non-destructive Read from Device
  358. ; Character devices only.
  359. ;
  360. ; If Input Status request returns Busy bit=0 (characters 
  361. ; waiting), ; the next character that would be read is returned 
  362. ; at Request Header + 13.  This character is not removed from
  363. ; the Input Buffer.  This basically provides the capability to 
  364. ; "look-ahead" by one character.
  365.  
  366. Nd_Input:
  367.  
  368.         jmp     Done
  369.  
  370.         page
  371.  
  372. ;
  373. ; Function 6  Input Status
  374. ; Character devices only.
  375. ;
  376. ; Sets the Returned Status word:
  377. ; Done bit = 1
  378. ; Busy bit = 1 read request would go to physical device
  379. ;          = 0 characters already in device buffer, read request
  380. ;              would return quickly.
  381. ;
  382. ; MS-DOS assumes all character devices have type-ahead buffer.
  383. ; If device does not have type-ahead buffer, should always
  384. ; return Busy bit=0 so MS-DOS will not hang.
  385.  
  386. Inp_Stat:
  387.  
  388.         jmp     Done
  389.  
  390.         page
  391.  
  392. ;
  393. ; Function 7  Flush Input Buffers
  394. ; Character devices only.
  395. ;
  396. ; Terminate all pending requests, i.e. the Input buffer is
  397. ; emptied.
  398.  
  399. Inp_Flush:
  400.  
  401.         jmp     Done
  402.  
  403.         page
  404.  
  405. ;
  406. ; Function 8  Write to Device
  407. ; Called with
  408. ;
  409. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  410. ; Request Header + 14  DWORD  Transfer address
  411. ; Request Header + 18  WORD   byte/sector count
  412. ; Request Header + 20  WORD   starting sector no. (block dev.)
  413. ;
  414. ; Returns the Return Status word set appropriately, and
  415. ; Request Header + 18  WORD   actual bytes or sectors transferred
  416.  
  417. Output: 
  418.  
  419.         jmp     Done
  420.  
  421.         page
  422.  
  423. ;
  424. ; Function 9  Write with Verify to Device
  425. ; Called with
  426. ;
  427. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  428. ; Request Header + 14  DWORD  Transfer address
  429. ; Request Header + 18  WORD   byte/sector count
  430. ; Request Header + 20  WORD   starting sector no. (block dev.)
  431. ;
  432. ; Returns the Return Status word set appropriately, and
  433. ; Request Header + 18  WORD   actual bytes or sectors transferred
  434.  
  435. Outp_Vfy: 
  436.  
  437.         jmp     Done
  438.  
  439.         page
  440.  
  441. ;
  442. ; Function 10  Output Status
  443. ;
  444. ; Character devices only.
  445. ;
  446. ; Sets the Returned Status word:
  447. ; Done bit = 1
  448. ; Busy bit = 1 write request would wait for completion of
  449. ;              current request
  450. ;          = 0 device idle, write request would start immediately.
  451. ;
  452.  
  453. Outp_Stat:
  454.  
  455.         jmp     Done
  456.  
  457.         page
  458.  
  459. ;
  460. ; Function 11  Flush Output Buffers
  461. ; Character devices only.
  462. ;
  463. ; Terminate pending requests.  The output buffer, if any,
  464. ; is emptied.
  465.  
  466. Outp_Flush:
  467.  
  468.         jmp     Done
  469.  
  470.         page
  471.  
  472. ;
  473. ; Function 12  I/O Control Write 
  474. ; Only called if IOCTL bit in Device Header Attribute word is set.
  475. ;
  476. ; Called with
  477. ;
  478. ; Request Header + 13  BYTE   Media descriptor byte from DPB
  479. ; Request Header + 14  DWORD  Transfer address
  480. ; Request Header + 18  WORD   byte/sector count
  481. ; Request Header + 20  WORD   starting sector no. (block dev.)
  482. ;
  483. ; Returns the Return Status word set appropriately, and
  484. ; Request Header + 18  WORD   actual bytes or sectors transferred
  485. ;
  486. ; No error check is performed on IOCTL calls.
  487.  
  488. Ioctl_Outp:
  489.  
  490.         jmp     Done
  491.  
  492.         page
  493.  
  494. ;
  495. ; Function 13  Device Open
  496. ;
  497. ; MS-DOS version 3.0 and above only.
  498. ; Only called if OPEN/CLOSE/RM bit set in Attribute word.
  499. ; May be used to manage local buffering.  Reference count
  500. ; is incremented keeping track of number of open files on
  501. ; the device.  On character devices can be used to send
  502. ; device initialization string, which can be set by IOCTL 
  503. ; Write.  Note that CON AUX and PRN devices are always open.
  504. ;
  505. ; Returns the Return Status word set to "Done".
  506. ;
  507. Dev_Open:
  508.  
  509.         jmp     Done
  510.  
  511.         page
  512.  
  513. ;
  514. ; Function 14  Device Close
  515. ;
  516. ; MS-DOS version 3.0 and above only.
  517. ; Only called if OPEN/CLOSE/RM bit set in Attribute word.
  518. ; May be used to manage local buffering.  Reference count
  519. ; is decremented keeping track of number of open files on
  520. ; the device; when count reaches zero all files have been closed 
  521. ; and the driver should flush buffers as user may change disks.
  522. ; On character devices can be used to send device post-I/O
  523. ; string such as a form feed, which can be set by IOCTL 
  524. ; Write.  Note that CON AUX and PRN devices are never closed.
  525. ;
  526. ; Returns the Return Status word set to "Done".
  527. ;
  528. Dev_Close:
  529.  
  530.         jmp     Done
  531.  
  532.         page
  533.  
  534. ;
  535. ; Function 15  Removeable Media
  536. ;
  537. ; MS-DOS version 3.0 and above only.
  538. ; Only called if OPEN/CLOSE/RM bit set in Attribute word
  539. ;    and device type is block.
  540. ;
  541. ; Returns the Return Status word set to "Done" and 
  542. ; Busy bit = 1 if media is non-removable.  
  543. ;          = 0 if media is removable.
  544. ;
  545. Rem_Media:
  546.  
  547.         jmp     Done
  548.  
  549.  
  550.         page
  551.  
  552. ; This Initialization code for the driver is called only
  553. ; once when the driver is loaded.  It is responsible for
  554. ; initializing the hardware, setting up any necessary 
  555. ; interrupt vectors, and it must return the address
  556. ; of the first free memory after the driver to the BDOS.
  557. ; If it is a block device driver, Init must also return the 
  558. ; address of the Bios Parameter Block pointer array; if all 
  559. ; units are the same, all pointers can point to the same BPB.
  560. ; Only MS-DOS services 01-0CH and 30H can be called by the 
  561. ; Initialization function. 
  562. ;
  563. ; In this example, Init returns its own address to the DOS as 
  564. ; the start of free memory after the driver, so that the memory 
  565. ; occupied by INIT will be reclaimed after it is finished 
  566. ; with its work.  
  567. ;
  568. ; Called with:
  569. ;
  570. ; Request Header + 18  DWORD pointer to the character after the "="
  571. ;                            on the CONFIG.SYS line that loaded 
  572. ;                            driver; this information is read only.
  573. ;                  22  BYTE  drive letter for first unit of a 
  574. ;                            block driver (0=A 1=B etc)
  575. ;                            (MS-DOS 3.x only)   
  576. ;
  577. ; Returns:
  578. ; Request Header + 13  BYTE  Number of units (block devices only)
  579. ;                + 14  DWORD address of first free memory above driver
  580. ;                + 18  DWORD BPB pointer array (block devices only)     
  581. ;
  582.  
  583. Init:                           ; Function 0
  584.                                 ; initialize device driver
  585.  
  586.         push    es              ; push Request Header addr
  587.         push    di
  588.  
  589.         mov     ah,9            ; print sign-on message
  590.         mov     dx,offset Ident
  591.         int     21h
  592.  
  593.         pop     di              ; restore Request Header addr
  594.         pop     es
  595.  
  596.                                 ; set first usable memory addr.
  597.         mov     word ptr es:[di.Address],offset Init
  598.         mov     word ptr es:[di.Address+2],cs
  599.  
  600.         jmp     Done
  601.  
  602.  
  603. Intr    endp
  604.  
  605.  
  606. Driver  endp
  607.  
  608. code    ends
  609.         
  610.         end     
  611. Capture buffer closed.
  612.  
  613. Press <CR> to continue: